/**
 * @file command.h
 * @brief Header file for command interpreter and ISO command handler
 *
 * @author Ricky Hariady (ricky.hariady@enter.web.id)
 *
 * @date 7/10/2013
 */

#define MAX_INST                20      ///< Maximum Instruction code (used by command maps)

/* File Operation */
#define	ISO_SELECT              0xA4      ///< ISO 7816-4 SELECT Instruction code
#define	ISO_READ_BINARY         0xB0      ///< ISO 7816-4 READ BINARY Instruction code
#define	ISO_UPDATE_BINARY       0xD6      ///< ISO 7816-4 UPDATE BINARY Instruction code
#define	ISO_READ_RECORD         0xB2      ///< ISO 7816-4 READ RECORD Instruction code
#define	ISO_UPDATE_RECORD       0xDC      ///< ISO 7816-4 UPDATE RECORD Instruction code
#define	ISO_APPEND_RECORD       0xE2      ///< ISO 7816-4 APPEND RECORD Instruction code

/* File Management */
#define	ISO_CREATE_FILE         0xE0      ///< ISO 7816-4 CREATE FILE Instruction code
#define	ISO_DELETE_FILE         0xE4      ///< ISO 7816-4 DELETE FILE Instruction code

/* Security */
#define	ISO_VERIFY              0x20      ///< ISO 7816-4 VERIFY Instruction code
#define	ISO_INTERNAL_AUTH       0x88      ///< ISO 7816-4 INTERNAL_AUTH Instruction code

/* Program Code Management */
#define	ISO_LOAD                0xDC      ///< ISO 7816-4 LOAD Instruction code
#define	ISO_INSTALL             0xDC      ///< ISO 7816-4 INSTALL Instruction code
#define	ISO_DELETE              0xDC      ///< ISO 7816-4 DELETE Instruction code

/* Data Transmission */
#define	ISO_GET_RESPONSE        0xC0  	///< ISO 7816-4 GET RESPONSE Instruction code

/*****************************/
/*        Enumeration        */
/*****************************/

/**
 * @brief command instruction enumeration
 */
typedef enum
{
        /* File Manipulation */
        Select,                 ///< Select Command
        ReadBinary,             ///< Read Binary Command
        UpdateBinary,           ///< Update Binary Command
        ReadRecord,             ///< Read Record Command
        UpdateRecord,           ///< Update Record Command
        /* File Management */
        CreateFile,             ///< Create File Command
        AppendRecord,           ///< Append Record Command
        DeleteFile,             ///< Delete File Command
        /* Security */
        Verify,                 ///< Verify Command
        InternalAuth,           ///< Internal Authentication Command
        /* Program code Management */
        Load,                   ///< Load Command
        Install,                ///< Install Command
        Delete,                 ///< Delete Command
        /* Data Transmission */
        GetResponse,            ///< Get Response Command
        MaxInst = MAX_INST      ///< End of Command enumeration
} inst_type;

/********************************/
/*        Data Structure        */
/********************************/

/**
 * @brief structure of command maps
 */
struct cmd_maps_struct
{
        uint8_t	        inst;      	        ///< instruction code
        int             (*handler)(int);        ///< pointer to command handler
} ;

/**************************/
/*        Variable        */
/**************************/

struct cmd_maps_struct  cmd_maps[MAX_INST];     ///< command maps

/**************************/
/*        Function        */
/**************************/

/**
 * @brief Interpret command APDU and call appropriate command handler.
 *
 * Call by transRx() when finish receiving command APDU,
 * Then call ResponseManager() to transmit the return APDU
 *
 * @param *rx_buffer    buffer for receive apdu
 * @param *apdu_res     pointer to apdu resources
 * @return none
 */
void CommandInterpreter(struct buffer_struct *rx_buffer, struct apdu_res_struct *apdu_res);

/********************************/
/* Standard ISO Command Handler */
/********************************/

/**
 * @brief ISO 7816-4 SELECT command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result\n
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_SELECT(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 READ BINARY command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_READ_BINARY(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 UPDATE BINARY command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_UPDATE_BINARY(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 READ RECORD command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_READ_RECORD(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 UPDATE RECORD command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_UPDATE_RECORD(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 CREATE FILE command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_CREATE_FILE(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 APPEND RECORD command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_APPEND_RECORD(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 DELETE FILE command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_DELETE_FILE(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 VERIFY command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_VERIFY(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 INTERNAL_AUTH command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_INTERNAL_AUTH(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 LOAD command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_LOAD(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 INSTALL command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_INSTALL(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 DELETE command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_DELETE(struct apdu_res_struct * apdu_res);

/**
 * @brief ISO 7816-4 GET RESPONSE command handler.
 *
 * Call by CommandInterpreter().
 * Executed the selected command and return the response type and data back to apdu_res 
 *
 * @param *apdu_res     pointer to APDU resources
 * @return Result
 *          Success     = OK
 *          Not Success = Error
 */
int cmd_GET_RESPONSE(struct apdu_res_struct * apdu_res);
